home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Magazine / Online / OpenURL / Developer / Source / handler.c < prev    next >
C/C++ Source or Header  |  1999-09-26  |  5KB  |  223 lines

  1. /*
  2. ** OpenURL-Handler - Asynch ARexx handler for openurl.library
  3. ** Written by Troels Walsted Hansen <troels@thule.no>
  4. ** Placed in the public domain.
  5. **
  6. ** This is the one and only source file for the handler.
  7. */
  8.  
  9. #include <proto/exec.h>
  10.  
  11. #include <clib/dos_protos.h>
  12. #include <clib/rexxsyslib_protos.h>
  13.  
  14. #include <pragmas/dos_pragmas.h>
  15. #include <pragmas/rexxsyslib_pragmas.h>
  16.  
  17. #include <exec/memory.h>
  18. #include <rexx/rxslib.h>
  19. #include <rexx/errors.h>
  20.  
  21. #include <string.h>
  22.  
  23. #include "handler.h"
  24.  
  25. #define SAVEDS __saveds
  26.  
  27. extern void kprintf(const char *, ...);
  28.  
  29. /**************************************************************************
  30. *
  31. * Prototypes for library and Local, non-library functions.
  32. *
  33. */
  34.  
  35. VOID SAVEDS HandlerProcessEntry(VOID);
  36. static BOOL SendRexxMsg(struct MsgPort *replyport, STRPTR rxport, STRPTR rxcmd);
  37.  
  38. /**************************************************************************
  39. *
  40. * Definitions and global variables.
  41. *
  42. */
  43.  
  44. struct ExecBase *SysBase;
  45. struct DosLibrary *DOSBase = NULL;
  46. struct RxsLib *RexxSysBase = NULL;
  47. static const char *version = "$VER: OpenURL-Handler 1.0 " __AMIGADATE__;
  48.  
  49. /**************************************************************************
  50. *
  51. * This function will be called when the handler is started.
  52. *
  53. */
  54.  
  55. VOID SAVEDS HandlerProcessEntry(VOID)
  56. {
  57.     struct Process *me;
  58.     struct HandlerMsg *starthm = NULL;
  59.     struct SignalSemaphore *ss;
  60.     ULONG sigs, sigmask, msgcount = 0;
  61.     struct MsgPort *mp = NULL;
  62.     struct Message *msg;
  63.  
  64.     SysBase = *(struct ExecBase **)4;
  65.     me = (struct Process *)FindTask(NULL);
  66.  
  67.     /* get startupmsg */
  68.  
  69.     while(!starthm)
  70.     {
  71.         /* should the handler accidentally be launched from somewhere other
  72.            than the library, it can be broken with CTRL-C */
  73.  
  74.         sigs = Wait((1 << me->pr_MsgPort.mp_SigBit) | SIGBREAKF_CTRL_C);
  75.         if(sigs & SIGBREAKF_CTRL_C) return;
  76.         starthm = (struct HandlerMsg *)GetMsg(&me->pr_MsgPort);
  77.     }
  78.  
  79.     ss = starthm->hm_Semaphore;
  80.     ObtainSemaphore(ss);
  81.  
  82.     /* initialise everything */
  83.  
  84.     if(!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 36)))
  85.         goto done;
  86.  
  87.     if(!(RexxSysBase = (struct RxsLib *)OpenLibrary("rexxsyslib.library", 33)))
  88.         goto done;
  89.  
  90.     if(!(mp = CreateMsgPort()))
  91.         goto done;
  92.  
  93.     /* reply startup msg to signal readyness */
  94.  
  95.     starthm->hm_Success = TRUE;
  96.     starthm->hm_MsgPort = mp;
  97.     ReplyMsg((struct Message *)starthm);
  98.     starthm = NULL;
  99.  
  100.     /* enter input loop */
  101.  
  102.     sigmask = (1 << mp->mp_SigBit) | SIGBREAKF_CTRL_C;
  103.  
  104.     for(;;)
  105.     {
  106.         sigs = Wait(sigmask);
  107.  
  108.         if(sigs & SIGBREAKF_CTRL_C) break;
  109.         else 
  110.         {
  111.             while((msg = GetMsg(mp)))
  112.             {
  113.                 if(msg->mn_Node.ln_Type == NT_REPLYMSG)
  114.                 {
  115.                     DeleteArgstring(((struct RexxMsg *)msg)->rm_Args[0]);
  116.                     DeleteRexxMsg((struct RexxMsg *)msg);
  117.                     msgcount--;
  118.                 }
  119.                 else
  120.                 {
  121.                     struct HandlerMsg *hm = (struct HandlerMsg *)msg;
  122.  
  123.                     if(hm->hm_Type    == HMT_AREXX)
  124.                     {
  125.                         hm->hm_Success = SendRexxMsg(mp, hm->hm_ARexxPort, hm->hm_ARexxCmd);
  126.                         if(hm->hm_Success) msgcount++;
  127.                     }
  128.  
  129.                     ReplyMsg(msg);
  130.                 }
  131.             }
  132.         }
  133.     }
  134.  
  135. done:
  136.     /* release semaphore to indicate we're no longer running.
  137.        this will stop the library from sending any more msgs */
  138.  
  139.     ReleaseSemaphore(ss);
  140.  
  141.     /* wait for return of all msgs */
  142.  
  143.     while(msgcount)
  144.     {
  145.         WaitPort(mp);
  146.  
  147.         while((msg = GetMsg(mp)))
  148.         {
  149.             if(msg->mn_Node.ln_Type == NT_REPLYMSG)
  150.             {
  151.                 DeleteArgstring(((struct RexxMsg *)msg)->rm_Args[0]);
  152.                 DeleteRexxMsg((struct RexxMsg *)msg);
  153.                 msgcount--;
  154.             }
  155.             else
  156.             {
  157.                 ((struct HandlerMsg *)msg)->hm_Success = FALSE;
  158.                 ReplyMsg(msg);
  159.             }
  160.         }
  161.     }
  162.  
  163.     /* empty out msgport */
  164.  
  165.     while((msg = GetMsg(mp)))
  166.     {
  167.         ((struct HandlerMsg *)msg)->hm_Success = FALSE;
  168.         ReplyMsg(msg);
  169.     }
  170.  
  171.     /* free resources */
  172.  
  173.     if(mp) DeleteMsgPort(mp);
  174.     CloseLibrary((struct Library *)RexxSysBase);
  175.     CloseLibrary((struct Library *)DOSBase);
  176.  
  177.     /* the startup msg needs to be replied now if a resource 
  178.        allocation failed */
  179.  
  180.     if(starthm)
  181.     {
  182.         starthm->hm_Success = FALSE;
  183.         ReplyMsg((struct Message *)starthm);
  184.     }
  185. }
  186.  
  187. /**************************************************************************/
  188.  
  189. static BOOL SendRexxMsg(struct MsgPort *replyport, STRPTR rxport, STRPTR rxcmd)
  190. {
  191.     struct RexxMsg *rxmsg;
  192.  
  193.     if((rxmsg = CreateRexxMsg(replyport, NULL, NULL)))
  194.     {
  195.         rxmsg->rm_Action = RXCOMM | RXFF_STRING | RXFF_NOIO;
  196.  
  197.         /* create the arg string */
  198.  
  199.         if((rxmsg->rm_Args[0] = CreateArgstring(rxcmd, strlen(rxcmd))))
  200.         {
  201.             struct MsgPort *targetport;
  202.  
  203.             /* find the named rexx port and put the rexx msg to it */
  204.  
  205.             Forbid();
  206.  
  207.             if((targetport = FindPort(rxport)))
  208.             {
  209.                 PutMsg(targetport, (struct Message *)rxmsg);
  210.                 Permit();
  211.                 return(TRUE);
  212.             }
  213.  
  214.             Permit();
  215.  
  216.             DeleteArgstring(rxmsg->rm_Args[0]);
  217.         }
  218.         DeleteRexxMsg(rxmsg);
  219.     }
  220.  
  221.     return(FALSE);
  222. }
  223.